package org.jeecg.modules.service;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.modules.doctor.entity.Doctor;
import org.jeecg.common.modules.doctor.entity.DoctorSchedule;
import org.jeecg.common.modules.doctor.entity.Hospital;
import org.jeecg.common.modules.doctor.service.IDoctorExtendService;
import org.jeecg.common.modules.doctor.service.IDoctorScheduleService;
import org.jeecg.common.modules.doctor.service.IDoctorService;
import org.jeecg.common.modules.doctor.service.IHospitalService;
import org.jeecg.common.system.util.ApiJwtUtil;
import org.jeecg.common.util.ApiJwtVo;
import org.jeecg.common.util.result.Result;
import org.jeecg.common.util.result.ResultMapper;
import org.jeecg.modules.vo.request.DoctorScheduleRequestVo;
import org.jeecg.modules.vo.respone.DoctorScheduleResponseVo;
import org.jeecg.modules.vo.respone.HospitalResponseVo;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.support.NullValue;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author guoyh
 * @ClassName ApiDoctorService
 * @Description
 * @since 2020/8/28 02:34
 **/
@Service
@Slf4j
public class ApiDoctorService {

    @Resource
    private IDoctorScheduleService doctorScheduleService;

    @Resource
    private IDoctorService doctorService;

    @Resource
    private IHospitalService hospitalService;
    @Resource
    private IDoctorExtendService  doctorExtendService;

    public List<HospitalResponseVo> getDoctorScheduleByDoctorId(String doctorId){
        //生成查询hospital
        Hospital queryHospital = new Hospital();
        queryHospital.setDoctorId(doctorId);
        List<Hospital> hospitals = hospitalService.list(Wrappers.lambdaQuery(queryHospital));  //查询
        //构造结果
        List<HospitalResponseVo> list = new ArrayList<>();
        for (Hospital hospital: hospitals) {
            HospitalResponseVo hospitalVo  = initHospitalResponseVo(hospital);
            DoctorSchedule querySchedule = new DoctorSchedule();
            querySchedule.setHospitalId(hospital.getId());
            querySchedule.setDoctorId(doctorId);
            List<DoctorSchedule> schedules = doctorScheduleService.list(Wrappers.lambdaQuery(querySchedule));
            for (DoctorSchedule schedule:schedules) {
                DoctorScheduleResponseVo scheduleVo = new DoctorScheduleResponseVo();
                scheduleVo.setScheduleWeek(schedule.getScheduleWeek());
                scheduleVo.setHospitalId(schedule.getHospitalId());
                scheduleVo.setStatus(schedule.getStatus());
                scheduleVo.setType(schedule.getType());
                hospitalVo.getSchedule().add(scheduleVo);
            }
            list.add(hospitalVo);
        }
        return list;
    }
    /**
     * 获取医生排班
     * @param accessToken
     * @return
     */
    public Result<List<HospitalResponseVo>> getDoctorSchedule(String accessToken,String sourceDoctorId){
        ApiJwtVo businessInfo = ApiJwtUtil.getBusinessInfo(accessToken);
        if (businessInfo == null || StringUtils.isBlank(businessInfo.getBusinessId())) {
            return ResultMapper.<List<HospitalResponseVo>>secureFail().setMsg("token无效");
        }
        String doctorId = Objects.nonNull(sourceDoctorId)?sourceDoctorId:businessInfo.getBusinessId();

        //生成查询hospital
        Hospital queryHospital = new Hospital();
        queryHospital.setDoctorId(doctorId);
        List<Hospital> hospitals = hospitalService.list(Wrappers.lambdaQuery(queryHospital));  //查询
        //构造结果
        List<HospitalResponseVo> list = new ArrayList<>();
        for (Hospital hospital: hospitals) {
            HospitalResponseVo hospitalVo  = initHospitalResponseVo(hospital);
            DoctorSchedule querySchedule = new DoctorSchedule();
            querySchedule.setHospitalId(hospital.getId());
            querySchedule.setDoctorId(doctorId);
            List<DoctorSchedule> schedules = doctorScheduleService.list(Wrappers.lambdaQuery(querySchedule));
            for (DoctorSchedule schedule:schedules) {
                DoctorScheduleResponseVo scheduleVo = new DoctorScheduleResponseVo();
                scheduleVo.setScheduleWeek(schedule.getScheduleWeek());
                scheduleVo.setHospitalId(schedule.getHospitalId());
                scheduleVo.setStatus(schedule.getStatus());
                scheduleVo.setType(schedule.getType());
                hospitalVo.getSchedule().add(scheduleVo);
            }
            list.add(hospitalVo);
        }

        return ResultMapper.<List<HospitalResponseVo>>ok().setData(list);
    }

    private HospitalResponseVo initHospitalResponseVo(Hospital hospital) {
        HospitalResponseVo vo = new HospitalResponseVo();
        vo.setCityId(hospital.getCityId());
        vo.setProvinceId(hospital.getProvinceId());
        vo.setContent(hospital.getContent());
        vo.setName(hospital.getName());
        vo.setId(hospital.getId());
        vo.setSchedule(new ArrayList<DoctorScheduleResponseVo>());
        return vo;
    }

    public Result<NullValue> setDoctorSchedule(DoctorScheduleRequestVo requestVo){
        log.info("param:{}", JSONUtil.toJsonStr(requestVo));
        ApiJwtVo businessInfo = ApiJwtUtil.getBusinessInfo(requestVo.getAccessToken());
        if (businessInfo == null || StringUtils.isBlank(businessInfo.getBusinessId())) {
            return ResultMapper.<NullValue>secureFail().setMsg("token无效");
        }
        String doctorId = StringUtils.isNoneBlank(requestVo.getDoctorId())?requestVo.getDoctorId():businessInfo.getBusinessId();
        Hospital hospital = new Hospital();
        hospital.setCityId(requestVo.getCityId());
        hospital.setProvinceId(requestVo.getProvinceId());
        hospital.setContent(requestVo.getContent());
        hospital.setCreateTime(new Date());
        hospital.setName(requestVo.getName());
        hospital.setDoctorId(doctorId);
        hospitalService.save(hospital);
        String hospitalId = hospital.getId();


        log.debug("添加排班 医院id"+hospitalId);
        List<DoctorSchedule> list = doctorScheduleService.queryByDoctorId(doctorId,hospitalId);
        doctorScheduleService.removeByIds(list.stream().map(DoctorSchedule::getId).collect(Collectors.toList()));
        Doctor doctor = doctorService.getById(doctorId);
        List<DoctorSchedule> add = requestVo.getSchedules().parallelStream().map(item -> this.buildDoctorSchedule(item,doctor.getName(),doctorId,hospitalId)).collect(Collectors.toList());
        doctorScheduleService.saveBatch(add);
        return ResultMapper.ok();
    }

    private DoctorSchedule buildDoctorSchedule(DoctorScheduleResponseVo request,String doctorName,String doctorId,String hospitalId){
        DoctorSchedule doctorSchedule = new DoctorSchedule();
        doctorSchedule.setCreateTime(new Date());
        doctorSchedule.setCreateBy(doctorName);
        doctorSchedule.setHospitalId(hospitalId);
        doctorSchedule.setDoctorId(doctorId);
        doctorSchedule.setScheduleWeek(request.getScheduleWeek());
        doctorSchedule.setType(request.getType());
        doctorSchedule.setStatus(request.getStatus());
        return doctorSchedule;
    }

    private DoctorSchedule getByType(String data,String doctorId){
        LambdaQueryWrapper<DoctorSchedule> query = Wrappers.lambdaQuery();
        query.eq(DoctorSchedule::getDoctorId,doctorId);
        String[] strings = data.split("_");
        query.eq(DoctorSchedule::getScheduleWeek,strings[0]);
        query.eq(DoctorSchedule::getType,strings[1]);
        return doctorScheduleService.getOne(query);
    }

    private DoctorScheduleResponseVo buildDoctorSchedule(DoctorSchedule doctorSchedule){
        DoctorScheduleResponseVo responseVo  = new DoctorScheduleResponseVo();
        BeanUtils.copyProperties(doctorSchedule,responseVo);
        return responseVo;
    }
}
